package com.zzyl.nursing.service.impl;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONUtil;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.nursing.domain.member.DevicePropertyData;
import com.zzyl.nursing.domain.member.FamilyElderData;
import com.zzyl.nursing.domain.member.FamilyMemberElder;
import com.zzyl.nursing.domain.member.FamilyMemberElderMy;
import com.zzyl.nursing.dto.FamilyDto;
import com.zzyl.nursing.dto.UserLoginRequestDto;
import com.zzyl.nursing.service.WechatService;
import com.zzyl.nursing.vo.DeviceDataByDay;
import com.zzyl.nursing.vo.DeviceShadowDataVo;
import com.zzyl.nursing.vo.LoginVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.FamilyMemberMapper;
import com.zzyl.nursing.domain.FamilyMember;
import com.zzyl.nursing.service.IFamilyMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import javax.annotation.Resource;

/**
 * 老人家属Service业务层处理
 * 
 * @author laoYe
 * @date 2025-05-29
 */
@Service
@Slf4j
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {
    @Autowired
    private FamilyMemberMapper familyMemberMapper;

    @Autowired
    private WechatService wechatService;

    @Resource
    private TokenService tokenService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    static List<String> DEFAULT_NICKNAME_PREFIX = ListUtil.of(
            "生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝"
    );

    /**
     * 查询老人家属
     * 
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询老人家属列表
     * 
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember)
    {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     * 
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember)
    {
        return save(familyMember) ? 1 : 0;
    }

    /**
     * 修改老人家属
     * 
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember)
    {
        return updateById(familyMember) ? 1 : 0;
    }

    /**
     * 批量删除老人家属
     * 
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除老人家属信息
     * 
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 小程序登录
     *
     * @param dto
     * @return
     */
    @Override
    public LoginVo login(UserLoginRequestDto dto) {
        // 构建返回对象
        LoginVo loginVo = new LoginVo();
        //    1、获取传过来的code
        String code = dto.getCode();
        //    2、远程调用小程序获取openid
        String openId = wechatService.getOpenId(code);
        //    3、获取手机号码
        String phone = wechatService.getPhone(dto.getPhoneCode());
        //    4、通过openid查询数据库family_member 家属信息
        FamilyMember memberInDb = lambdaQuery().eq(FamilyMember::getOpenId, openId).one();
        //    5、如果不存在则 新增家属信息, 生成一个随机名称
        FamilyMember familyMember = new FamilyMember();
        if(null == memberInDb){
            familyMember.setOpenId(openId);
            // 生成随机名称
            familyMember.setName(getRandomName(phone));
            familyMember.setPhone(phone);
            save(familyMember);
            //设置登录名称
            loginVo.setNickName(familyMember.getName());
        }else {
            //设置登录名称
            loginVo.setNickName(memberInDb.getName());
            familyMember.setId(memberInDb.getId());
            //    6、存在，判断手机号码是否不一致，不一致则更新手机号码
            if(!memberInDb.getPhone().equals(phone)){
                familyMember.setPhone(phone);
                updateById(familyMember);
            }
        }
        //    7、生成token返回
        Map<String,Object> claims = new HashMap<>();
        claims.put("userId", familyMember.getId());
        claims.put("nickName", loginVo.getNickName());
        String token = tokenService.createToken(claims);

        loginVo.setToken(token);
        return loginVo;
    }

//    @Override
//    public List<DeviceShadowDataVo> queryServiceProperties(String iotId) {
//        List<DeviceShadowDataVo> voList = new ArrayList<>();
//        ShowDeviceShadowRequest request = new ShowDeviceShadowRequest();
//        request.withDeviceId(iotId);
//        try {
//            ShowDeviceShadowResponse response = client.showDeviceShadow(request);
//            //System.out.println(response.toString());
//            List<DeviceShadowData> list = response.getShadow();
//            for (DeviceShadowData deviceShadowData : list) {
//                // 上报的数据，里面属性名与值
//                DeviceShadowProperties reported = deviceShadowData.getReported();
//                LinkedHashMap<String, Object> propertiesData = (LinkedHashMap) reported.getProperties();
//                // 上报数据的时间
//                String eventTime = reported.getEventTime();
//                LocalDateTime activeTime = LocalDateTimeUtil.parse(eventTime, "yyyyMMdd'T'HHmmss'Z'");
//                //日期时区转换, 当前所在的时区
//                LocalDateTime activeDateTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC))
//                        // 转时区,获取系统中的时区
//                        .withZoneSameInstant(ZoneId.systemDefault())
//                        .toLocalDateTime();
//                // 把map中的每个数据转成List
//                voList = propertiesData.entrySet().stream().map(entry -> {
//                    DeviceShadowDataVo vo = new DeviceShadowDataVo();
//                    vo.setEventTime(activeDateTime);
//                    vo.setFunctionId(entry.getKey());
//                    vo.setValue(entry.getValue().toString());
//                    return vo;
//                }).collect(Collectors.toList());
//            }
//        } catch (Exception e) {
//            log.error("查询设备最新数据失败", e);
//            throw new ServiceException("查询设备最新数据失败");
//        }
//        return voList;
//    }

    @Override
    public List<DeviceDataByDay> queryDeviceDataListByDay(String iotId, String functionId, Long startTime, Long endTime) {
        LocalDateTime startDateTime = LocalDateTimeUtil.of(startTime);
        LocalDateTime endDateTime = LocalDateTimeUtil.of(endTime);
        List<DeviceDataByDay> list = familyMemberMapper.queryDeviceDataListByDay(iotId, functionId, startDateTime, endDateTime);

        return list;
    }

    @Override
    public List<DeviceDataByDay> queryDeviceDataListByWeek(String iotId, String functionId, Long startTime, Long endTime) {
        LocalDateTime startDateTime = LocalDateTimeUtil.of(startTime);
        LocalDateTime endDateTime = LocalDateTimeUtil.of(endTime);
        List<DeviceDataByDay> list = familyMemberMapper.queryDeviceDataListByWeek(iotId, functionId, startDateTime, endDateTime);

        return list;
    }

//    @Nullable
//    private List<DeviceDataByDay> getFromRedis1(String iotId, String functionId, Long startTime, Long endTime) {
//
//        try {
////
//            Object jsonData = redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_LAST_DATA, iotId);
//
//            if (jsonData == null) {
//                log.info("Redis 中无数据，iotid={}", iotId);
//                return null;
//            }
//
//            // 解析 JSON 为 Map 列表
//            List<Map> dataList = JSONUtil.toList((String) jsonData, Map.class);
//            // 输出 dataList
//            log.info("Redis 中数据：{}", dataList);
//
//            /**
//             * 获取指定时间段的数据  aaa 是测试数据
//             */
//
//            List<DeviceDataByDay> aaa = new ArrayList<>();
//            List<DeviceDataByDay> result = new ArrayList<>();
//            result = ((dataList.stream()
//                    .filter(map -> functionId.equals(map.get("functionId"))) // 过滤指定功能点
//                    .map(map -> {
//
//                        Long timestamp = Long.valueOf(map.get("alarmTime").toString());
//                        Double value = Double.parseDouble(map.get("dataValue").toString());
//
//                        LocalDateTime dateTime = Instant.ofEpochMilli(timestamp)
//                                .atZone(ZoneId.systemDefault())
//                                .toLocalDateTime();
//
//                        String formattedHour = formatToLocalHour1(dateTime); // 格式化为 "HH:00"
//
//                        DeviceDataByDay deviceDataByDay = new DeviceDataByDay(formattedHour, value);
//                        if (isWithinTimeRange2(timestamp, startTime, endTime)) {
//                            deviceDataByDay = new DeviceDataByDay(formattedHour, value);
//                            aaa.add(deviceDataByDay);
//                        }
//
//                        return deviceDataByDay;
//                    })
//                    .collect(Collectors.toList())));
//
//            return aaa;
//        } catch (Exception e) {
//            log.error("Redis 数据解析失败", e);
//            return null;
//        }
//
//    }

//    @Nullable
//    private List<DeviceDataByDay> getFromRedis2(String iotId, String functionId, Long startTime, Long endTime) {
//
//        try {
//            Object jsonData = redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_LAST_DATA, iotId);
//
//            if (jsonData == null) {
//                log.info("Redis 中无数据，iotid={}", iotId);
//                return null;
//            }
//
//            // 解析 JSON 为 Map 列表
//            List<Map> dataList = JSONUtil.toList((String) jsonData, Map.class);
//            // 输出 dataList，dataList是redis中所有的数据
//            log.info("Redis 中数据：{}", dataList);
//            /**
//             *
//             */
//            return dataList.stream()
//                    // 1️⃣ 筛选指定设备 + 功能ID 的数据
//                    .filter(map -> iotId.equals(map.get("iotId")))
//                    .filter(map -> functionId.equals(map.get("functionId")))
//                    .filter(map -> {
//                        Long timestamp = Long.valueOf(map.get("alarmTime").toString());
//                        return timestamp >= startTime && timestamp <= endTime;
//                    })
//                    // 2️⃣ 映射成临时对象（日期 + 数值）
//                    .map(map -> {
//                        Long timestamp = Long.valueOf(map.get("alarmTime").toString());
//                        Double value = Double.parseDouble(map.get("dataValue").toString());
//                        LocalDateTime dateTime = Instant.ofEpochMilli(timestamp)
//                                .atZone(ZoneId.systemDefault())
//                                .toLocalDateTime();
//                        String dateStr = formatDateToLocalDate(dateTime); // 如："6月3日"
//                        return new DeviceDataByDay(dateStr, value);
//                    })
//                    // 3️⃣ 按日期分组并计算平均值
//                    .collect(Collectors.groupingBy(
//                            DeviceDataByDay::getDateTime,
//                            Collectors.averagingDouble(DeviceDataByDay::getDataValue)
//                    ))
//                    // 4️⃣ 转换回 DeviceDataByDay 列表
//                    .entrySet().stream()
//                    .map(entry -> new DeviceDataByDay(entry.getKey(), entry.getValue()))
//                    // 5️⃣ 按日期排序
//                    .sorted(Comparator.comparing(DeviceDataByDay::getDateTime))
//                    .collect(Collectors.toList());
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//
//
//    }
//    // 格式化为 "几月几日"
    private String formatDateToLocalDate(LocalDateTime dateTime) {
        int monthValue = dateTime.getMonthValue();  // 获取月份（1~12）
        int dayOfMonth = dateTime.getDayOfMonth();  // 获取日（1~31）
        return monthValue + "月" + dayOfMonth + "日";
        //输出几月几日

    }

    private String formatToLocalHour2(LocalDateTime time) {
        int month = time.getMonthValue();
        int day = time.getDayOfMonth();
        return String.format("%02d.%02d", month, day);
    }


    private String formatToLocalHour1(LocalDateTime time) {
        int hour = time.getHour();
        return String.format("%02d:00", hour);
    }

    /**
     * 判断时间是否在指定范围内
     */
    private boolean isWithinTimeRange2(Long targetTimestamp, Long startTime, Long endTime) {
        try {
            return targetTimestamp >= startTime && targetTimestamp <= endTime;
        } catch (Exception e) {
            log.warn("时间判断异常：{}", e.getMessage());
            return false;
        }
    }

    private String getRandomName(String phone) {
        // 随机组装昵称，词组+手机号后四位
        String nickName = DEFAULT_NICKNAME_PREFIX.get((int) (Math.random() * DEFAULT_NICKNAME_PREFIX.size()))
                + StringUtils.substring(phone, 7);
        return nickName;
    }

    /**
     * 绑定家人
     */
    @Override
    public FamilyMemberElder selectFamilyMemberId(FamilyDto family) {
        FamilyMemberElder familyMemberElder = new FamilyMemberElder();
        // 根据family从老人表中获取老人id
        Long elderId = familyMemberMapper.selectElderId(family);
        familyMemberElder.setElderId(elderId);
        //从工具类里面获取当先登录用户的Id
        //当前登录用户信息放入LoginUser类里面
        //查询登录用户的id
        Long userId = UserThreadLocal.getUserId();
//        LoginUser loginUser = (LoginUser) SecurityUtils.getLoginUser();
//        familyMemberElder.setFamilyMemberId(loginUser.getUserId());
        familyMemberElder.setRemark(family.getRemark());
        familyMemberElder.setFamilyMemberId(userId);
        return familyMemberElder;
    }

    /**
     * 查询家人列表
     */
    @Override
    public List<FamilyMemberElderMy> selectFamilyMemberElderMy() {
        //查询登录用户的id
        Long userId = UserThreadLocal.getUserId();
        List<FamilyMemberElderMy> list = familyMemberMapper.selectFamilyMemberElderMy(userId);
        return list;
    }

    /**
     * 查询已绑定的家人列表 分页查询
     */
    @Override
    public List<FamilyElderData> selectFamilyElderData() {
        //查询登录用户的id
        Long userId = UserThreadLocal.getUserId();
        List<FamilyElderData> familyElderData = familyMemberMapper.selectFamilyElderData(userId);

        return familyElderData;
    }

    /**
     * 获取绑定设备的数据
     */
    @Override
    public List<DevicePropertyData> getDeviceData(String deviceId) {
        return familyMemberMapper.getDeviceData(deviceId);
    }
}
